﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Helena.Models;
using Helena.Areas.Productos.Models;
using Helena.Areas.Vendedores.Models;

namespace Helena.Areas.Salidas.Models
{
    public class LogicaSalida :InterfazLogicaSalida
    {
        DBContext Salida_contexto = new DBContext();
        DBGenericQueriesUtil<Salida> Tabla;
        DBGenericQueriesUtil<DetalleSalida> tabla_detalle;
        DBGenericQueriesUtil<Producto> tabla_Producto;
        DBGenericQueriesUtil<DetalleProducto> tabla_Detalle_Producto;

        #region Comun

        LogicaProducto logica_producto = new LogicaProducto();
        
        public DBContext context_publico { get { return Salida_contexto; } }

        public LogicaSalida()
        {
            Tabla = new DBGenericQueriesUtil<Salida>(Salida_contexto, Salida_contexto.t_salida);
            tabla_detalle = new DBGenericQueriesUtil<DetalleSalida>(Salida_contexto, Salida_contexto.t_DetalleSalida);
            tabla_Producto = new DBGenericQueriesUtil<Producto>(Salida_contexto, Salida_contexto.t_Productos);
            tabla_Detalle_Producto = new DBGenericQueriesUtil<DetalleProducto>(Salida_contexto, Salida_contexto.t_DetalleProductos);
        }

        public void i_AgregarSalida(SalidaView salida)
        {
            Tabla.agregarElemento(salida.deserializa(this));
        }

        public void i_ModificarSalida(SalidaView salida)
        {
            Salida s = salida.deserializa(this);
            Tabla.modificarElemento(s, s.ID);
        }

        public void i_EliminarSalida(int id)
        {
            Tabla.eliminarElemento_logico(id);
        }

        public List<SalidaView> i_RetornarSalidas()
        {
            List<Salida> s = Tabla.retornarTodos();
            List<SalidaView> s_v = new List<SalidaView>();

            foreach (Salida salida in s)
                    s_v.Add(new SalidaView(salida));
            return s_v;
        }

        public SalidaView i_RetornarSalida(int id)
        {
            try
            {
                Salida s = Tabla.retornarUnSoloElemento(id);
                SalidaView s_v = new SalidaView(s);
                return s_v;
            }
            catch
            { 
                return null;
            }
        }

        #endregion

        #region Detalles

        public List<DetalleSalidaView> DetallesDeUnaSalida(int salidaID)
        {
            IEnumerable<DetalleSalida> antes = from detalles in tabla_detalle.retornarTodos()
                                               where detalles.SalidaID == salidaID && detalles.Estado == true
                                               select detalles;

            List<DetalleSalida> detallesDeUnaSalida = antes.ToList();
            List<DetalleSalidaView> salida = new List<DetalleSalidaView>();

            foreach (DetalleSalida uno in detallesDeUnaSalida)
                if (uno.Estado)
                {
                    DetalleSalidaView temp = new DetalleSalidaView(uno);
                    salida.Add(temp);
                }
            return salida;
        }
        
        public void AgregarDetalleaSalida(int id, DetalleSalidaView dsv)
        {
            bool pertenece = false;
            List<DetalleSalida> detalles = tabla_detalle.retornarTodos()
                                           .Where(e => e.SalidaID == id)
                                           .Where(e => e.Estado == true)
                                           .ToList();

            foreach (DetalleSalida d in detalles)
            {
                if (d.ProductoID == dsv.ProductoID)
                {
                    pertenece = true;
                }
            }

            if (pertenece == false)
            {
                tabla_detalle.agregarElemento(dsv.deserializa(this));
            }

            //***********Resta a la tabla productos****************
            List<DetalleProducto> subproducto = tabla_Detalle_Producto.retornarTodos().Where(d => d.ProductoCID == dsv.ProductoID).ToList();
            Producto producto = null;

            if (subproducto.Count == 0)
            {
                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad - dsv.Cantidad;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }
            else
            {
                foreach (DetalleProducto dp in subproducto)
                {
                    producto = tabla_Producto.retornarUnSoloElemento(dp.ProductoID);
                    producto.cantidad = producto.cantidad - dsv.Cantidad * dp.Cantidad;
                    tabla_Producto.modificarElemento(producto, producto.ID);
                }

                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad - dsv.Cantidad;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }        
            //*****************************************************
        }

        public void i_ModificarDetalle(int id, DetalleSalidaView dsv)
        {
            //no se puede modificar un detalle xq se altera el stock del producto
            //y no se sabe cuanto era inicialmente
        }

        public void i_EliminarDetalle(int id, DetalleSalidaView dsv)
        {
            tabla_detalle.eliminarElemento_logico(dsv.ID);

            //***********Suma a la tabla productos****************
            List<DetalleProducto> subproducto = tabla_Detalle_Producto.retornarTodos().Where(d => d.ProductoCID == dsv.ProductoID).ToList();
            Producto producto = null;

            if (subproducto.Count == 0)
            {
                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad + dsv.Cantidad;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }
            else
            {
                foreach (DetalleProducto dp in subproducto)
                {
                    producto = tabla_Producto.retornarUnSoloElemento(dp.ProductoID);
                    producto.cantidad = producto.cantidad + dsv.Cantidad * dp.Cantidad;
                    tabla_Producto.modificarElemento(producto, producto.ID);
                }

                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad + dsv.Cantidad;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }  
            //*****************************************************
        }

        #endregion
               
    }
}
